from django.conf import settings
from django.contrib.auth.hashers import make_password
from django.core.files.base import ContentFile
from django.core.files.storage import default_storage
from django.core.files.uploadedfile import InMemoryUploadedFile
from django.utils.decorators import method_decorator
from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
from rest_framework import serializers
from rest_framework.parsers import MultiPartParser, JSONParser
from rest_framework.permissions import IsAuthenticated, BasePermission

from system.models import Users
from utils.myView import CustomView
from utils.serializer import CustomModelSerializer
from utils.swagger import ViewSwagger


def get_storage_avatar_url(avatar_path):
    host = settings.MINIOHTTP + settings.MINIOWEBHOST + ':' + settings.MINIOWEBPORT
    return host + "/" + settings.MINIOPROXY + '/' + avatar_path


class AuthObjPermission(BasePermission):
    """
    验证用户有无该对象的权限
    """
    def has_object_permission(self, request, view, obj):
        user_id = request.user.id
        if obj.id == user_id:
            return True
        else:
            return False


class UsersInfoSerializer(CustomModelSerializer):
    avatar_url = serializers.SerializerMethodField(required=False, label='头像', help_text='头像', read_only=True)
    avatar = serializers.ImageField(required=False, label='头像', help_text='头像', write_only=True)

    def get_avatar_url(self, instance):
        return get_storage_avatar_url(instance.avatar) if instance.avatar else instance.avatar

    def validate_password(self, value):
        """
        对密码进行验证
        """
        password = self.initial_data.get("password")
        if password:
            return make_password(value)
        return value

    def validate(self, attrs):
        avatar = attrs.get('avatar')
        if avatar and isinstance(avatar, InMemoryUploadedFile):
            path = default_storage.save(f'userinfo/{avatar.name}', ContentFile(avatar.read()))      # , name='bbb.png'
            attrs['avatar'] = path
            # 删除原来的头像文件
            if self.instance.avatar:
                default_storage.delete(self.instance.avatar)
        return attrs

    class Meta:
        model = Users
        fields = ['id', 'username', 'nickname', 'email', 'mobile', 'gender', 'create_datetime', 'avatar_url',
                  'password', 'avatar']
        read_only_fields = ['id', 'create_datetime', 'username']
        # extra_kwargs可以重写字段的属性
        extra_kwargs = {
            "password": {"write_only": True, 'required': False},
        }


class UserInfoSwagger(ViewSwagger):
    post_req_params = [
        openapi.Parameter(name='avatar', in_=openapi.IN_FORM, default='头像', type=openapi.TYPE_FILE, required=False),
    ]


@method_decorator([swagger_auto_schema(**UserInfoSwagger.post())], name='post')
class UserInfoView(CustomView):
    """
    tags:
        用户信息
    post:
        更新头像
    """
    permission_classes = [IsAuthenticated, AuthObjPermission]
    serializer_class = UsersInfoSerializer
    queryset = Users.objects.all()
    lookup_field = 'pk'
    parser_classes = [MultiPartParser, JSONParser]

    def post(self, request, *args, **kwargs):
        kwargs['partial'] = True
        return self.update(request, *args, **kwargs)




